﻿using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.Web.Mvc.Authorization;
using MyCompanyName.AbpZeroTemplate.Authorization;
using MyCompanyName.AbpZeroTemplate.Daybooks;
using MyCompanyName.AbpZeroTemplate.Daybooks.Dto;
using MyCompanyName.AbpZeroTemplate.Web.Controllers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Abp.AutoMapper;

namespace MyCompanyName.AbpZeroTemplate.Web.Areas.Okr.Controllers
{
    using Abp.Domain.Uow;
    using Abp.Extensions;
    using MyCompanyName.AbpZeroTemplate.Authorization.Users;
    using MyCompanyName.AbpZeroTemplate.Daybooks.Exporting;
    using MyCompanyName.AbpZeroTemplate.Web.Areas.Okr.Models;

    [AbpMvcAuthorize]
    public class DaybookController : AbpZeroTemplateControllerBase
    {
        //有业务的，那用肯定得用AppService来操作了。里面有权限，审计，参数校验等
        private readonly DaybookAppService _daybookAppService;
        // 对于简单的数据CRUD，可以直接注入仓储进行操作。
        private readonly IRepository<Daybook, long> _daybookRepository;
        private readonly UserManager _userManager;
        private readonly DayBookExcelExporter _export;

        public DaybookController(DaybookAppService daybookAppService, IRepository<Daybook, long> daybookRepository, UserManager userManager, DayBookExcelExporter export)
        {
            _daybookAppService = daybookAppService;
            _daybookRepository = daybookRepository;
            _userManager = userManager;
            _export = export;
        }


        // GET: Okr/Daybook
        public ActionResult Index()
        {
            return View();
        }



        [HttpGet]
        // [AbpMvcAuthorize(AppPermissions.Pages_Okr_Daybook_Create, AppPermissions.Pages_Okr_Daybook_Edit)]
        public ActionResult Edit(int? id)
        {
            var current = _daybookAppService.GetDaybookForEdit(new NullableIdInput { Id = id });
            return View(current);
        }

        [HttpPost]
        // [AbpMvcAuthorize(AppPermissions.Pages_Okr_Daybook_Create, AppPermissions.Pages_Okr_Daybook_Edit)]
        public async Task<ActionResult> Edit(int? id, DateTime BookDay, string Category, string Remark, FormCollection form)
        {
            CreateOrUpdateDaybookDto dto = new CreateOrUpdateDaybookDto()
            {
                Book = new DaybookEditDto()
                {
                    AccountId = AbpSession.UserId.Value,
                    AccountName = User.Identity.Name,
                    BookDay = BookDay.Date,// 这个值，让编辑吗？
                    Id = id,
                    Category = Category,
                    Remark = Remark
                },
                Items = new List<DaybookItemEditDto>()
            };

            for (int i = 0; i < 10; i++)
            {
                string _id = form["Id_" + i];
                string _State = form["State_" + i];
                string _ManHour = form["ManHour_" + i];
                string _Work = form["Work_" + i];
                string _Customer = form["Customer_" + i];
                string _Product = form["Product_" + i];

                if (string.IsNullOrEmpty(_State) ||
                    string.IsNullOrEmpty(_ManHour) ||
                    string.IsNullOrEmpty(_Customer) ||
                    string.IsNullOrEmpty(_Product) ||
                    string.IsNullOrEmpty(_Work))
                {
                    continue;
                }

                var _s = _State.ToEnum<Daybooks.WorkStatus>();
                if (_s == WorkStatus.NUL)
                {
                    continue;
                }

                var item = new DaybookItemEditDto()
                {
                    //Id = _id.To<int>(),

                    AccountId = dto.Book.AccountId,
                    AccountName = dto.Book.AccountName,
                    BookDay = dto.Book.BookDay,

                    Index = dto.Items.Count,

                    Work = _Work,
                    State = _s,
                    Customer = _Customer,
                    Product = _Product,
                    ManHour = _ManHour.To<Single>(),
                    Remark = form["Remark_" + i]
                };
                if (!string.IsNullOrEmpty(_id))
                {
                    item.Id = _id.To<int>();
                }
                dto.Items.Add(item);
            }

            await _daybookAppService.CreateOrUpdateEdition(dto);

            return RedirectToAction("My");
        }


        [ChildActionOnly]
        // [AbpMvcAuthorize(AppPermissions.Pages_Okr_Daybook_My, AppPermissions.Pages_Okr_Daybook_Manager)]
        public ActionResult DayItems(int id)
        {
            var tmp = _daybookAppService.GetDaybookForEdit(new NullableIdInput { Id = id });
            return View(tmp);
        }


        //public ActionResult My() 
        //{
        //    return View();
        //}


        [HttpGet]
        //   [AbpMvcAuthorize(AppPermissions.Pages_Okr_Daybook_My)]
        public ActionResult My(GetDaybooksInput input)
        {
            input.AccountId = AbpSession.UserId;
            var lst = _daybookAppService.GetDaybooks(input);
            return View(lst);
        }

        [HttpGet]
        //   [AbpMvcAuthorize(AppPermissions.Pages_Okr_Daybook_Manager)]
        public ActionResult Manager(GetDaybooksInput input)
        {
            input.MaxResultCount = 30;
            var lst = _daybookAppService.GetDaybooks(input);
            return View(lst);
        }


        public ActionResult Statistics(string CustomerName, string ProjectName)
        {
            List<StatisticsModel> result = new List<StatisticsModel>();
            if (!string.IsNullOrEmpty(CustomerName) && !string.IsNullOrEmpty(ProjectName))
            {
                result = GetStatistics(CustomerName, ProjectName);
            }
            return View(result);
        }

        public List<StatisticsModel> GetStatistics(string CustomerName, string ProjectName)
        {
            List<StatisticsModel> result = new List<StatisticsModel>();
            var search = _daybookAppService.GetDaybookStatistics(CustomerName, ProjectName);
            var users = GetUsers();
            foreach (var item in users)
            {
                var myDayBook = search.Where(x => x.AccountId == item.Id);
                var first = myDayBook.OrderBy(x => x.BookDay).FirstOrDefault();
                var end = myDayBook.OrderByDescending(x => x.BookDay).FirstOrDefault();
                result.Add(new StatisticsModel
                {
                    Customer = CustomerName,
                    Project = ProjectName,
                    UserId = item.Id,
                    Name = item.Name,
                    Hours = myDayBook.Sum(q => { double b = 0; double.TryParse(q.ManHour, out b); return b; }),
                    Proportion = ((myDayBook.Sum(q => { double b = 0; double.TryParse(q.ManHour, out b); return b; })
                    / search.Sum(q => { double b = 0; double.TryParse(q.ManHour, out b); return b; })) * 100).ToString("f2"),
                    StartTime = first != null ? first.BookDay.ToString("yyyy-MM-dd") : "",
                    EndTime = end != null ? end.BookDay.ToString("yyyy-MM-dd") : ""
                });
            }
            ViewBag.CName = CustomerName;
            ViewBag.PName = ProjectName;
            return result;
        }


        [UnitOfWork]
        public virtual List<User> GetUsers()
        {
            return _userManager.Users.ToList();
        }



        public ActionResult Export(string CustomerName, string ProjectName)
        {
            var res = GetStatistics(CustomerName, ProjectName);
            List<GetStatisticsExportDto> dtos = res.Select(x => new GetStatisticsExportDto()
            {
                Customer = x.Customer,
                Project = x.Project,
                EndTime = x.EndTime,
                Hours = x.Hours,
                Name = x.Name,
                Proportion = x.Proportion,
                StartTime = x.StartTime,
                UserId = x.UserId
            }).ToList();
            var dto = _export.ExportToFile(dtos);
            return Json(dto, JsonRequestBehavior.AllowGet);
        }

    }
}